package com.ctw.tinyservices.id.core.snowflake.holder;

import com.ctw.tinyservices.id.common.entity.IdWorkerId;
import com.ctw.tinyservices.id.core.snowflake.exception.CheckLastTimeException;
import com.ctw.tinyservices.id.core.snowflake.service.IdWorkerIdService;

/**
 * @author TongWei.Chen 2022/4/8 14:30
 *
 * MySQL
 **/
public class MySQLIdSnowflakeHolder extends AbstractIdSnowflakeHolder {
    private IdWorkerIdService workerIdService;

    private volatile static MySQLIdSnowflakeHolder singleton;
    public static MySQLIdSnowflakeHolder getInstance(Integer port, IdWorkerIdService workerIdService) {
        if (singleton == null) {
            synchronized (MySQLIdSnowflakeHolder.class) {
                if (singleton == null) {
                    singleton = new MySQLIdSnowflakeHolder(port, workerIdService);
                }
            }
        }
        return singleton;
    }

    private MySQLIdSnowflakeHolder(Integer port, IdWorkerIdService workerIdService) {
        super(port);
        this.workerIdService = workerIdService;
    }

    @Override
    protected void doProcess() {
        IdWorkerId workerIdEntity = workerIdService.getOrInsert(ip, port, listenAddress);
        if (workerIdEntity.getMaxTimestamp() > System.currentTimeMillis()) {
            throw new CheckLastTimeException("init timestamp check error,db workid  node maxTimestamp gt this node time");
        }
        this.workerId = workerIdEntity.getId();
    }

    @Override
    protected void doUpdateMaxTimestamp() {
        workerIdService.updateMaxTimestamp(workerId, System.currentTimeMillis());
    }

}
